package com.majie.utils.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 时间的工具类
 *
 * @author majie
 * @date 2018/6/19.
 */
public class DateUtils {

    /**
     * 默认的时间格式
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 默认zoneId
     */
    public static final String DEFAULT_ZONE_ID = "Asia/Shanghai";

    /**
     * 大于
     */
    public static final int BIGGER = 1;
    /**
     * 小于
     */
    public static final int LESS = -1;
    /**
     * 等于
     */
    public static final int EQUALS = 0;


    /**
     * LocalDate2Date
     */
    public static Date localDate2Date(LocalDate localDate) {
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * LocalDateTime2Date
     */
    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        Instant instant = localDateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * Date2LocalDate
     */
    public static LocalDate date2LocalDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.toLocalDate();
    }


    /**
     * Date2LocalDateTime
     */
    public static LocalDateTime date2LocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * Date2LocalTime
     */
    public static LocalTime date2LocalTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.toLocalTime();
    }


    /**
     * LocalTime2date
     */
    public static Date localTime2date(LocalTime localTime) {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        Instant instant = localDateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * LocalDateTime 转到毫秒
     * localDateTime2Millis
     */
    public static long localDateTime2Millis(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        Instant instant = localDateTime.atZone(zone).toInstant();
        return instant.toEpochMilli();
    }

    /**
     * LocalDateTime 转到秒
     * localDateTime2Seconds
     */
    public static long localDateTime2Seconds(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.of(DEFAULT_ZONE_ID);
        Instant instant = localDateTime.atZone(zone).toInstant();
        return instant.getEpochSecond();
    }

    /**
     * StrDate2Date
     *
     * @param strDate    string时间
     * @param dateFormat 格式类型,如果为空使用默认的格式,yyyy-MM-dd HH:mm:ss
     * @return date
     */
    public static Date strDate2Date(String strDate, String dateFormat) {
        //如果为空使用默认的格式
        if (StringUtils.isBlank(dateFormat)) {
            dateFormat = DEFAULT_DATE_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        try {
            return sdf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Date2StrDate
     *
     * @param date       date时间
     * @param dateFormat 格式类型,如果为空使用默认的格式,yyyy-MM-dd HH:mm:ss
     * @return string
     */
    public static String date2StrDate(Date date, String dateFormat) {
        if (StringUtils.isBlank(dateFormat)) {
            dateFormat = DEFAULT_DATE_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(date);
    }

    /**
     * LocalDateTime2StrDate
     *
     * @param localDateTime localDateTime
     * @param dateFormat    格式类型,如果为空使用默认的格式,yyyy-MM-dd HH:mm:ss
     * @return string
     */
    public static String localDateTime2StrDate(LocalDateTime localDateTime, String dateFormat) {
        if (StringUtils.isBlank(dateFormat)) {
            dateFormat = DEFAULT_DATE_FORMAT;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
        return localDateTime.format(df);
    }

    /**
     * StrDate2LocalDateTime
     *
     * @param strDate    strDate
     * @param dateFormat 时间格式
     * @return string
     */
    public static LocalDateTime strDate2LocalDateTime(String strDate, String dateFormat) {
        if (StringUtils.isBlank(dateFormat)) {
            dateFormat = DEFAULT_DATE_FORMAT;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
        return LocalDateTime.parse(strDate, df);
    }

    /**
     * 计算两个date日期之间的间隔
     *
     * @param date1      时间1
     * @param date2      时间2
     * @param chronoUnit 单位
     * @return long
     */
    public static long intervalOfDates(Date date1, Date date2, ChronoUnit chronoUnit) {
        LocalDateTime localDateTime1 = date2LocalDateTime(date1);
        LocalDateTime localDateTime2 = date2LocalDateTime(date2);
        return localDateTime1.until(localDateTime2, chronoUnit);
    }

    /**
     * 比较两个日期的先后顺序
     *
     * @param date1 时间1
     * @param date2 时间2
     * @return int  -1表示date1 < date2,1表示date1 > date2,0表示相等
     */
    public static int compareDates(Date date1, Date date2) {
        LocalDateTime localDateTime1 = date2LocalDateTime(date1);
        LocalDateTime localDateTime2 = date2LocalDateTime(date2);
        if (localDateTime1.isBefore(localDateTime2)) {
            return LESS;
        } else if (localDateTime1.isAfter(localDateTime2)) {
            return BIGGER;
        } else {
            return EQUALS;
        }
    }

    /**
     * 测试
     */
    public static void main(String[] args) {
        System.out.println(localDate2Date(null));
        System.out.println(localDateTime2Date(LocalDateTime.now()));
        System.out.println(localTime2date(LocalTime.now()));

        System.out.println(date2LocalDate(new Date()));
        System.out.println(date2LocalDateTime(new Date()));
        System.out.println(date2LocalTime(new Date()));

        System.out.println(localDateTime2Millis(LocalDateTime.now()));
        System.out.println(localDateTime2Seconds(LocalDateTime.now()));


        System.out.println(strDate2Date("2018-06-19 10:38:19", DEFAULT_DATE_FORMAT));

        System.out.println(date2StrDate(new Date(), DEFAULT_DATE_FORMAT));

        System.out.println(localDateTime2StrDate(LocalDateTime.now(), null));
        System.out.println(strDate2LocalDateTime("2018-06-19 10:38:19", null));

        System.out.println(intervalOfDates(new Date(), strDate2Date("2018-06-10 10:38:19", null), ChronoUnit.DAYS));
        System.out.println(compareDates(new Date(), new Date()));
    }
}
